/*
**************************************************************************************************************
*                                        卡处理执行函数	  消费
*
*  描 述： 卡处理执行函数
*
*  配 置： 
*
*  注 意：  
*
*  作 者： 
*
*  版 本： V1.0     
*
*  日 期： 2010-06-30
*
*        Copyright (c) 2008-2009   Brand-NEW C.A.P Electronics Technology CO.,LTD
*
**************************************************************************************************************
*/
#define	_SYS_GLOBE_VAR_ 
#include "..\..\Prj\INC\LIB_Includes.H"



/*
**************************************************************************************************************
*										         常 量
**************************************************************************************************************
*/
#define UP_CARD_SUCC		0	//不显示，正常

#define UP_CARD_MEMERR		4	//存储器错误
#define UP_CARD_MEMFULL		5	//存储器满

#define UP_CARD_NSUPPORT	10	//不支持此类型卡
#define UP_CARD_TYPEERR		20	//卡类型错误
#define UP_CARD_NENBLE		30	//卡片未启用
#define UP_CARD_DISABLE		40	//卡片已停用
#define UP_CARD_UNUSUAL 	50	//非同张卡
#define UP_CARD_STATERR		60	//卡状态错误
#define UP_CARD_BLACK		70	//黑卡
#define UP_CARD_LOSS		80	//挂失卡
#define UP_CARD_LOCK		90	//卡已锁定
#define UP_CARD_NFARE		100	//无票价
#define UP_CARD_PROHIBIT	110	//禁止交易
#define UP_CARD_FARELERR	120	//票价等级错误
#define UP_CARD_NPURSE		130	//无钱包
#define UP_CARD_INSPECTION	140	//请年检
#define UP_CARD_ILLEGAL		150	//非法卡
#define UP_CARD_NCONTINUE	160	//禁止连刷
#define UP_CARD_BALANCE		170	//余额不足
#define UP_CARD_OFFSITE		180	//异地卡无钱包禁止使用
				
#define UP_CARD_PSAMERR		200	//PSAM错误
#define UP_CARD_MAC1ERR		210	//MAC1计算失败

#define UP_CARD_NPUBKEY		300 //公钥下载未完成
#define UP_CARD_NICPAR		310 //参数下载未完成
//#define UP_CARD_ZERO		320 //交易金额不能为零
#define UP_CARD_REJECT		325 //脱机拒绝
#define UP_CARD_LIMITMONEY	330 //超出非接触脱机交易限额
#define UP_CARD_NOPPSE		335 //选择非接触支付环境失败
#define UP_CARD_NOSUPPORT	337 //终端不支持此应用
#define UP_CARD_DDAERR		340 //脱机认证失败

#define UP_CARD_UNKNOWN		999 //未知错误    
					 
/*
**************************************************************************************************************
*										         类 型
**************************************************************************************************************
*/

/*
**************************************************************************************************************
*										         类 型
**************************************************************************************************************
*/

/*
**************************************************************************************************************
*										         变 量
**************************************************************************************************************
*/
U08 ErrRec[7];
U32 CardDataBufferNumTmp;
U08 TlvBuffer[255],TlvBufferlen;
U08 BalanceDisStat=0;
U32 ExchInitStat;
/*
**************************************************************************************************************
*         								         函 数
**************************************************************************************************************
*/
/*********************************************************************
* 名称: 查找白名单 
* 功能: 在Flash中寻找卡BIN,并且核对卡的状态
* 入口:
*       ID: 白名单存储区对应的区号
* 	    *pBlacklist:    卡号
*       BlacklistState: 状态(允许消费的状态)
*       *pTemp:         查找位置
&
* 返回: 0,  允许消费
	    非0,不允许消费 
**********************************************************************
*/
U32 UP_ADV_FindWhitelist( U32 ID, U08 *pWhitelist, U08 WhitelistState, U08 *pTemp )
{
    U08 sta[8];
    U32 rcode;

	// rcode = APP_FindBlacklist( ID, pWhitelist, sta, pTemp );
	// if( rcode != 0 )										 //没有找到白名,返回失败
	// { return 1; }
	// //如果找到了需要再核对状态
	// if( ( ( sta[0] & 0xf0 ) >> 4 ) != WhitelistState )		 //状态不允许消费
	// { return 2; }
	
	return 0;												 //返回成功,可以消费
}
/*
**************************************************************************************************************
* 独立查询余额指令 	 外部需要进行寻卡

*  参  数：Balance	 余额
* 
*  返  回：0    成功
*          1  	终端不支持
*          2  	失败 可重新寻卡再次尝试
**************************************************************************************************************
*/
U32 UP_Card_GetBalance(U32 *Balance)
{
	U32 rcode;
	U08 buf[20],IcBackBalance[6];
	U08 tmp;
	RTC_CLOCK pTime;
	UP_TlvNumStat = 0;	
	UP_TlvDDealtaInit();
	UP_CardTlvDataLenInit();
	UP_TradeTlvDataLenInit();
	UP_ICPParmInit();
	memset(UP_TLV9f06tmpSet,0,sizeof(__UP_TLV9f06tmp)*16);
	UP_TlvNum = 0;
	memcpy(UP_TVL9F66DataTmp,UP_PosTLVSet.TVL9F66Data , 4);
	UP_PosTLVSet.TVL9F66Len = 4;
	rcode = ICF_SelectAID( "2PAY.SYS.DDF01", 0x0E, UP_Icc );   //选择QPBOC目录 
	if( rcode != 0x9000 )						
	{
		goto END;
	}

	rcode = UP_TlvDataAnalysisAndFarming(&gpRcvBuffer[0], (U16)(Grcv_Len-2), buf, buf, 1);	   //TLV数据解析
	if((rcode)&&(UP_TlvNum==0))
	{		    
		goto END;
	}
	UP_9F06Sort();	
	memcpy(UP_ICPParm.TVL9F06,UP_TLV9f06tmpSet[0].TLV9f06tmpData,UP_TLV9f06tmpSet[0].TLV9f06tmpLen);
	UP_ICPParm.TVL9F06Len = UP_TLV9f06tmpSet[0].TLV9f06tmpLen;
	rcode = ICF_SelectAID( (const unsigned char *)UP_ICPParm.TVL9F06, UP_ICPParm.TVL9F06Len, UP_Icc );  //选择电子现金应用
	if( rcode != 0x9000 )						
	{ 
		goto END;
	}
	rcode = UP_TlvDataAnalysisAndFarming(&gpRcvBuffer[0], (U16)(Grcv_Len-2), &tmp, &tmp, 1);	   //TLV数据解析
	if((rcode) && (UP_CardTLVSet.TVL9F38PDOL.Len == 0))
	{   
		DEF_SysCard_Debug;
		goto END;
	}
	if(UP_CardTLVSet.TVL9F38PDOL.Len == 0)
	{
		DEF_SysCard_Debug;
		goto END;
	}
	if(strstr((const char*)&UP_CardDataBuffer[UP_CardTLVSet.TVL9F38PDOL.Seat],"\x9F\x66")==0)
	{
		DEF_SysCard_Debug;
		goto END;
	}
	RTC_ReadSysTime( &pTime );				//强制重新获取一次时间
	UP_TradeInformation.DealTime[0] = pTime.Year_H;
    UP_TradeInformation.DealTime[1] = pTime.Year_L;
    UP_TradeInformation.DealTime[2] = pTime.Month;
    UP_TradeInformation.DealTime[3] = pTime.Day;
    UP_TradeInformation.DealTime[4] = pTime.Hour;
    UP_TradeInformation.DealTime[5] = pTime.Minute;
    UP_TradeInformation.DealTime[6] = pTime.Second;		//暂存当前系统时钟
/************************************************************
* GPO前准备工作
*************************************************************/
	rcode = UP_TradeTlvDataSetLenAndValue(0);			  //设置交易相关TLV数据
	if(rcode)							  
	{		 
		memcpy(UP_TVL9F66DataTmp,UP_PosTLVSet.TVL9F66Data , 4);
		DEF_SysCard_Debug;
		goto END;
	}
	memset(TlvBuffer,0,255);
	UP_TlvDataAnalysisAndFarming(&UP_CardDataBuffer[UP_CardTLVSet.TVL9F38PDOL.Seat], UP_CardTLVSet.TVL9F38PDOL.Len, TlvBuffer, &TlvBufferlen, 0);	  //根据电子现金返回的PDOL组建GPO命令数据部分
	CardDataBufferNumTmp = UP_CardDataBufferNum;		    //暂存TLV数据缓冲区位置信息  以便做异常处理	
	memcpy(UP_TVL9F66DataTmp,UP_PosTLVSet.TVL9F66Data , 4);
/************************************************************
* GPO命令
*************************************************************/	
	rcode = UP_GPO( TlvBuffer, TlvBufferlen, UP_Icc );   //发送GPO命令进行应用初始化
/************************************************************
* 读取余额
*************************************************************/
	rcode = UP_GetBalanceEC(IcBackBalance, UP_Icc);	 //读取电子现金余额
	if( rcode != 0x9000 )							
	{
		goto END;	
	}
	memset(buf, 0, 20);
	sprintf((char*)buf,"%02X%02X%02X%02X%02X%02X", IcBackBalance[0], IcBackBalance[1], IcBackBalance[2], IcBackBalance[3], IcBackBalance[4], IcBackBalance[5]);
	*Balance = atoi((const char*)buf);	//保存卡内余额
	return 0;
	END:
	if(rcode>6000)
	{rcode = 1;}
	else
	{rcode = 2;}
	return rcode;
}					   
/*
**************************************************************************************************************
* 独立指获取卡帐号指令 	 外部需要进行寻卡

输出参数:	Bin57			标签57中卡号部分　此缓冲区不小于10字节	 卡帐号以"D"结尾 
  			Bin57len		标签57中卡号部分长度　　如果没有标签57则返回0
返回：0:成功		非0:失败 
**************************************************************************************************************
*/
U32 UP_Card_GetBin(U08 *Bin57, U32 *Bin57len)
{
	U32 rcode;
	U08 buf[20];
	U32 i;
	U08 tmp;
	RTC_CLOCK pTime;
	UP_TlvNumStat = 0;	
	UP_TlvDDealtaInit();
	UP_CardTlvDataLenInit();
	UP_TradeTlvDataLenInit();
	UP_ICPParmInit();
	memset(UP_TLV9f06tmpSet,0,sizeof(__UP_TLV9f06tmp)*16);
	UP_TlvNum = 0;
	memcpy(UP_TVL9F66DataTmp,UP_PosTLVSet.TVL9F66Data , 4);
	UP_PosTLVSet.TVL9F66Len = 4;
	*Bin57len = 0;
	rcode = ICF_SelectAID( "2PAY.SYS.DDF01", 0x0E, UP_Icc );   //选择QPBOC目录 
	if( rcode != 0x9000 )						
	{
		goto END;
	}

	rcode = UP_TlvDataAnalysisAndFarming(&gpRcvBuffer[0], (U16)(Grcv_Len-2), buf, buf, 1);	   //TLV数据解析
	if((rcode)&&(UP_TlvNum==0))
	{		    
		goto END;
	}
	UP_9F06Sort();	
	memcpy(UP_ICPParm.TVL9F06,UP_TLV9f06tmpSet[0].TLV9f06tmpData,UP_TLV9f06tmpSet[0].TLV9f06tmpLen);
	UP_ICPParm.TVL9F06Len = UP_TLV9f06tmpSet[0].TLV9f06tmpLen;
	rcode = ICF_SelectAID( (const unsigned char *)UP_ICPParm.TVL9F06, UP_ICPParm.TVL9F06Len, UP_Icc );  //选择电子现金应用
	if( rcode != 0x9000 )						
	{ 
		goto END;
	}
	rcode = UP_TlvDataAnalysisAndFarming(&gpRcvBuffer[0], (U16)(Grcv_Len-2), &tmp, &tmp, 1);	   //TLV数据解析
	if((rcode) && (UP_CardTLVSet.TVL9F38PDOL.Len == 0))
	{   
		DEF_SysCard_Debug;
		goto END;
	}
	if(UP_CardTLVSet.TVL9F38PDOL.Len == 0)
	{
		DEF_SysCard_Debug;
		goto END;
	}
	if(strstr((const char*)&UP_CardDataBuffer[UP_CardTLVSet.TVL9F38PDOL.Seat],"\x9F\x66")==0)
	{
		DEF_SysCard_Debug;
		goto END;
	}
	RTC_ReadSysTime( &pTime );				//强制重新获取一次时间
	UP_TradeInformation.DealTime[0] = pTime.Year_H;
    UP_TradeInformation.DealTime[1] = pTime.Year_L;
    UP_TradeInformation.DealTime[2] = pTime.Month;
    UP_TradeInformation.DealTime[3] = pTime.Day;
    UP_TradeInformation.DealTime[4] = pTime.Hour;
    UP_TradeInformation.DealTime[5] = pTime.Minute;
    UP_TradeInformation.DealTime[6] = pTime.Second;		//暂存当前系统时钟
/************************************************************
* GPO前准备工作
*************************************************************/
	rcode = UP_TradeTlvDataSetLenAndValue(0);			  //设置交易相关TLV数据
	if(rcode)							  
	{		 
		memcpy(UP_TVL9F66DataTmp,UP_PosTLVSet.TVL9F66Data , 4);
		DEF_SysCard_Debug;
		goto END;
	}
	memset(TlvBuffer,0,255);
	UP_TlvDataAnalysisAndFarming(&UP_CardDataBuffer[UP_CardTLVSet.TVL9F38PDOL.Seat], UP_CardTLVSet.TVL9F38PDOL.Len, TlvBuffer, &TlvBufferlen, 0);	  //根据电子现金返回的PDOL组建GPO命令数据部分
	CardDataBufferNumTmp = UP_CardDataBufferNum;		    //暂存TLV数据缓冲区位置信息  以便做异常处理	
	memcpy(UP_TVL9F66DataTmp,UP_PosTLVSet.TVL9F66Data , 4);
/************************************************************
* GPO命令
*************************************************************/	
	rcode = UP_GPO( TlvBuffer, TlvBufferlen, UP_Icc );   //发送GPO命令进行应用初始化	 
	if(rcode != 0x9000)							  			//余额、交易计数更新 卡片自动置防拔位
	{			
		DEF_SysCard_Debug;					
		goto END;
	}
	rcode = UP_TlvDataAnalysisAndFarming(&gpRcvBuffer[0], (U16)Grcv_Len-2, buf, buf, 1);	//TLV数据解析
	if(rcode)
	{
		DEF_SysCard_Debug;
		goto END;
	}
	*Bin57len = 0;
	for(i=0;i<UP_CardTLVSet.TVL57CD2.Len;i++)
	{
		if(((UP_CardDataBuffer[UP_CardTLVSet.TVL57CD2.Seat+i]&0xF0) !=0xD0 )&&((UP_CardDataBuffer[UP_CardTLVSet.TVL57CD2.Seat+i]&0x0F) !=0x0D ))
		{
			(*Bin57len)++;	
		}
		else if(((UP_CardDataBuffer[UP_CardTLVSet.TVL57CD2.Seat+i]&0x0F) ==0x0D ))
		{
			(*Bin57len)++;	
		 	break;
		}
		else if(((UP_CardDataBuffer[UP_CardTLVSet.TVL57CD2.Seat+i]&0xF0) ==0xD0 ))
		{
		 	break;
		}
	}
	if(*Bin57len>10)
	{*Bin57len = 10;}
	if(*Bin57len)
	{
		memcpy(Bin57, &UP_CardDataBuffer[UP_CardTLVSet.TVL57CD2.Seat], *Bin57len);
	}
	return 0;
	END:
	return rcode;
}
/*
**************************************************************************************************************
*                                       选择银联ＱＰＢＯＣ支付环境
*  参  数：无
* 
*  返  回：0    卡片校验成功
*          非0  卡片校验失败
**************************************************************************************************************
*/
U32 UP_Card_SelectPPSE( void )
{
	U16 rcode;	
	U08 tmp;
//	U08 buf[20]={0};
//	U32 len;  
	
	UP_TlvNumStat = 0;	
	UP_TlvDDealtaInit();
	UP_CardTlvDataLenInit();
	UP_TradeTlvDataLenInit();
	UP_ICPParmInit();
	memset(UP_TLV9f06tmpSet,0,sizeof(__UP_TLV9f06tmp)*16);
	UP_TlvNum = 0;
	memcpy(UP_TVL9F66DataTmp,UP_PosTLVSet.TVL9F66Data , 4);
	UP_PosTLVSet.TVL9F66Len = 4;
	rcode = UP_Card_CheckMemoryCaKeyAndIcPar();	  //检查存储器、公钥下载、IC卡参数下载状态
	if( rcode )						
	{	
		DEF_SysCard_Debug;
		return rcode; 
	}
	rcode = ICF_SelectAID( "2PAY.SYS.DDF01", 0x0E, UP_Icc );   //选择QPBOC目录 
	if( rcode != 0x9000 )						
	{
		ICC_PCD_RadioOff();	
		DEF_SysCard_Debug;
		return UP_CARD_NOPPSE;
	}

	rcode = UP_TlvDataAnalysisAndFarming(&gpRcvBuffer[0], (U16)(Grcv_Len-2), &tmp, &tmp, 1);	   //TLV数据解析
	if((rcode)&&(UP_TlvNum==0))
	{		    
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	}
	UP_9F06Sort();
	return UP_CARD_SUCC;
}
/*
**************************************************************************************************************
* 【1】                                      CPU 卡 片 校 验 
*  
*  描  述：对卡片进行校验，包括：当前消费模式是否允许先放卡，对卡片的黑名单，特殊标记进行判断等。
*          当一项校验失败时，错误提示在此函数中完成。调用此函数只判断成功与失败。
*
*  参  数：无
* 
*  返  回：0    卡片校验成功
*          非0  卡片校验失败
**************************************************************************************************************
*/
U32 UP_Card_Check( void )
{
	U16 rcode;	
	U08 tmp;
	RTC_CLOCK pTime;
//	U08 buf[20]={0},IcBackBalance[6];
	k1:
	memcpy(UP_ICPParm.TVL9F06,UP_TLV9f06tmpSet[UP_TlvNumStat].TLV9f06tmpData,UP_TLV9f06tmpSet[UP_TlvNumStat].TLV9f06tmpLen);
	UP_ICPParm.TVL9F06Len = UP_TLV9f06tmpSet[UP_TlvNumStat].TLV9f06tmpLen;
	UP_CardDataBufferNum = 0;
	if(UP_SysCfg.NormalOrShow == 0)
	{
		rcode = UP_FindRec_ICPar( UP_ICPParm.TVL9F06,UP_ICPParm.TVL9F06Len);				//查找终端是否有此应用信息  对IC卡参数进行检索
		if(rcode != 0)
		{
			UP_TlvNumStat++;
			if(UP_TlvNumStat<UP_TlvNum)
			{
				goto k1;
			}
			DEF_SysCard_Debug;
			return UP_CARD_NOSUPPORT;
		}
	}
	rcode = ICF_SelectAID( (const unsigned char *)UP_ICPParm.TVL9F06, UP_ICPParm.TVL9F06Len, UP_Icc );  //选择电子现金应用
	if( rcode != 0x9000 )						
	{
		UP_TlvNumStat++;
		if(UP_TlvNumStat<UP_TlvNum)
		{
			goto k1;
		}
		ICC_PCD_RadioOff();	  
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	}

	rcode = UP_TlvDataAnalysisAndFarming(&gpRcvBuffer[0], (U16)(Grcv_Len-2), &tmp, &tmp, 1);	   //TLV数据解析
	if((rcode) && (UP_CardTLVSet.TVL9F38PDOL.Len == 0))
	{   
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	}
	if(UP_CardTLVSet.TVL9F38PDOL.Len == 0)
	{
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	}
	if(strstr((const char*)&UP_CardDataBuffer[UP_CardTLVSet.TVL9F38PDOL.Seat],"\x9F\x66")==0)
	{
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	}
	
	RTC_ReadSysTime( &pTime );				//强制重新获取一次时间
	UP_TradeInformation.DealTime[0] = pTime.Year_H;
    UP_TradeInformation.DealTime[1] = pTime.Year_L;
    UP_TradeInformation.DealTime[2] = pTime.Month;
    UP_TradeInformation.DealTime[3] = pTime.Day;
    UP_TradeInformation.DealTime[4] = pTime.Hour;
    UP_TradeInformation.DealTime[5] = pTime.Minute;
    UP_TradeInformation.DealTime[6] = pTime.Second;		//暂存当前系统时钟
	memcpy( UP_TradeInformation.LastCardPhySN, UP_TradeInformation.CardPhySN, 4 );   //记住通过验证的卡片SNR 

	return UP_CARD_SUCC;
}

/*
**************************************************************************************************************
* 【3】                               高 级 的 完 成 CPU 卡 扣 钱 写 卡 交 易    
*                            
*  描　述：
*
*  参  数：无
* 
*  返  回：0   交易成功
*          非0 交易失败
*
**************************************************************************************************************
*/

U32 UP_Card_ExchInit(void )
{
	U32 rcode;
	U08 buf[100]={0};
	BalanceDisStat = 0;
    rcode = UP_Card_CheckTradeMoney();	 //交易金额检查
	if(rcode)							  
	{		    
		DEF_SysCard_Debug;
		goto END;
	}
k2:
	memset(ErrRec,0,sizeof(ErrRec));

/************************************************************
* GPO前准备工作
*************************************************************/
	rcode = UP_TradeTlvDataSetLenAndValue(UP_TradeInformation.DealMoney);			  //设置交易相关TLV数据
	if(rcode)							  
	{		 
		memcpy(UP_TVL9F66DataTmp,UP_PosTLVSet.TVL9F66Data , 4);
		DEF_SysCard_Debug;
		rcode = UP_CARD_UNKNOWN;
		goto END;
	}
	memset(TlvBuffer,0,255);
	UP_TlvDataAnalysisAndFarming(&UP_CardDataBuffer[UP_CardTLVSet.TVL9F38PDOL.Seat], UP_CardTLVSet.TVL9F38PDOL.Len, TlvBuffer, &TlvBufferlen, 0);	  //根据电子现金返回的PDOL组建GPO命令数据部分
	CardDataBufferNumTmp = UP_CardDataBufferNum;		    //暂存TLV数据缓冲区位置信息  以便做异常处理	
	memcpy(UP_TVL9F66DataTmp,UP_PosTLVSet.TVL9F66Data , 4);
/************************************************************
* GPO命令
*************************************************************/	
	rcode = UP_GPO( TlvBuffer, TlvBufferlen, UP_Icc );   //发送GPO命令进行应用初始化	 
	if(rcode != 0x9000)							  			//余额、交易计数更新 卡片自动置防拔位
	{			
		if(rcode == 0x6985)
		{
			UP_TlvNumStat++;
			if(UP_TlvNumStat<UP_TlvNum)
			{
				k3:
				rcode = UP_Card_Check();
				if(rcode)
				{
					UP_TlvNumStat++;
					if(UP_TlvNumStat<UP_TlvNum)
					{
						goto k3;
					}
					else
					{
						DEF_SysCard_Debug;
						rcode = UP_CARD_UNKNOWN;
						goto END;
					}
				}
				else
				{
					goto k2;
				}
			}		
		}
		DEF_SysCard_Debug;					
		rcode = UP_CARD_UNKNOWN;
		goto END;
	}
	rcode = UP_TlvDataAnalysisAndFarming(&gpRcvBuffer[0], (U16)Grcv_Len-2, buf, buf, 1);	//TLV数据解析
	if(rcode)
	{
		DEF_SysCard_Debug;
		rcode = UP_CARD_UNKNOWN;
		goto END;
	}
	rcode = UP_Card_CheckTLVData_Necessary();		//GPO命令返回中必要数据检查及卡片新余额暂存
	if(rcode)
	{   
		goto END;
	}
	

	rcode = UP_TVL94AFLCheck(&UP_CardDataBuffer[UP_CardTLVSet.TVL94AFL.Seat], UP_CardTLVSet.TVL94AFL.Len);
	if(rcode)
	{ 
		DEF_SysCard_Debug;
		rcode = UP_CARD_UNKNOWN;
		goto END;
	}
	rcode = UP_CARD_SUCC;
	END:
	UP_TradeInformation.OldPurseBalance = UP_TradeInformation.NewPurseBalance = 0;
	if(UP_CardTLVSet.TVL9F5D.Len)									
	{
		BalanceDisStat=1;
		sprintf((char*)buf,"%02X%02X%02X%02X%02X%02X", UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+1], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+2], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+3], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+4], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+5]);		   	//保存卡内余额
		UP_TradeInformation.NewPurseBalance = atoi((const char*)buf);
		if(ErrRec[6] == 0)
		{
			if(rcode == UP_CARD_SUCC)
			{UP_TradeInformation.OldPurseBalance = UP_TradeInformation.NewPurseBalance+UP_TradeInformation.DealMoney;}
			else
			{
				UP_TradeInformation.OldPurseBalance = UP_TradeInformation.NewPurseBalance;
				if(UP_TradeInformation.OldPurseBalance<UP_TradeInformation.DealMoney)
				{
					rcode = UP_CARD_BALANCE;
				}
			}	
		}
	}		 	
	return rcode;//交易成功
}

/*
**************************************************************************************************************
* 【3】                               高 级 的 完 成 CPU 卡 扣 钱 写 卡 交 易    
*                            
*  描　述：
*
*  参  数：无
* 
*  返  回：0   交易成功
*          非0 交易失败
*
**************************************************************************************************************
*/

U32 UP_Card_ToExch( void )
{
	U32 rcode=0;
	U08 buf[20]={0};
	U08 IcBackBalance[6];
	if((UP_CardTLVSet.TVL9F5D.Len==0)&&(UP_CardTLVSet.TVL9F79ECBALANCE.Len==0))	
	{
		if( UP_GetBalanceEC(IcBackBalance, UP_Icc) == 0x9000 )		//读取电子现金余额					
		{
			UP_CardTLVSet.TVL9F79ECBALANCE.Len = 6;		//电子现金余额			   6	R	n
			UP_CardTLVSet.TVL9F79ECBALANCE.Seat = UP_CardDataBufferNum;
			memcpy(&UP_CardDataBuffer[UP_CardDataBufferNum], IcBackBalance, 6);
			UP_CardDataBufferNum += 6;
			sprintf((char*)buf,"%02X%02X%02X%02X%02X%02X", IcBackBalance[0], IcBackBalance[1], IcBackBalance[2], IcBackBalance[3], IcBackBalance[4], IcBackBalance[5]);
			UP_TradeInformation.NewPurseBalance = atoi((const char*)buf);	//保存卡内余额
			BalanceDisStat=1;
			ErrRec[6] = 1;
			if(rcode == UP_CARD_SUCC)
			{UP_TradeInformation.OldPurseBalance = UP_TradeInformation.NewPurseBalance+UP_TradeInformation.DealMoney;}
			else
			{
				UP_TradeInformation.OldPurseBalance = UP_TradeInformation.NewPurseBalance;
				if(UP_TradeInformation.OldPurseBalance<UP_TradeInformation.DealMoney)
				{
					return UP_CARD_BALANCE;
				}
			}
		}
	}
	else
	{
		if(UP_TradeInformation.OldPurseBalance<UP_TradeInformation.DealMoney)
		{
			return UP_CARD_BALANCE;
		}
	}
	rcode = UP_TlvRecDataReading(&UP_CardDataBuffer[UP_CardTLVSet.TVL94AFL.Seat], UP_CardTLVSet.TVL94AFL.Len, ErrRec);
	memset(buf, 0, 20);	
	if(UP_CardTLVSet.TVL9F5D.Len)								
	{
		BalanceDisStat=1;
		sprintf((char*)buf,"%02X%02X%02X%02X%02X%02X", UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+1], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+2], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+3], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+4], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+5]);		   	//保存卡内余额
		UP_TradeInformation.NewPurseBalance = atoi((const char*)buf);
		if(ErrRec[6] == 0)
		{
			UP_TradeInformation.OldPurseBalance = UP_TradeInformation.NewPurseBalance+UP_TradeInformation.DealMoney;	
		}
	}		 	
	else if(BalanceDisStat)
	{
		UP_TradeInformation.NewPurseBalance = UP_TradeInformation.OldPurseBalance - UP_TradeInformation.DealMoney;
	}
	if( rcode != 0 )							 //根据AFL文件列表读取相关文件信息   
	{											//如果成功读完最后一个文件则清除防拔位	 
		if(rcode == 3)
		{
			UP_HookExchWriteRecErr();	
			DEF_SysCard_Debug;		  
			return UP_CARD_NENBLE;				
		}	
		else if(rcode == 4)	
		{
			UP_HookExchWriteRecErr();
			DEF_SysCard_Debug;			  
			return UP_CARD_DISABLE;				
		}						 
		else if(rcode == 2)								
		{
			rcode = UP_CpuCard_ErrProc( TlvBuffer, TlvBufferlen, CardDataBufferNumTmp, ErrRec );
			if(rcode == 0)
			{goto kk2;}
			else
			{
				ICC_PCD_RadioOff();
				DEF_SysCard_Debug;
				return UP_CARD_UNKNOWN;
			}
		}
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	} 

kk2:
	memset(buf, 0, 20);	
	if(UP_CardTLVSet.TVL9F5D.Len)									
	{
		BalanceDisStat=1;
		sprintf((char*)buf,"%02X%02X%02X%02X%02X%02X", UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+1], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+2], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+3], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+4], UP_CardDataBuffer[UP_CardTLVSet.TVL9F5D.Seat+5]);		   	//保存卡内余额
		UP_TradeInformation.NewPurseBalance = atoi((const char*)buf);
		if(ErrRec[6] == 0)
		{
			UP_TradeInformation.OldPurseBalance = UP_TradeInformation.NewPurseBalance+UP_TradeInformation.DealMoney;	
		}
	}		 	
	else if(BalanceDisStat)
	{
		UP_TradeInformation.NewPurseBalance = UP_TradeInformation.OldPurseBalance - UP_TradeInformation.DealMoney;
	}
	//DisplayClearAll( 0 ); 
	//DisplayString( 0, 0, 0, 0, 0, "脱机认证中...   ", 0 );
	//DisplayString( 0, 0, 0, 2, 0, "可以移除用户卡  ", 0 );
	if(UP_Tlv5APANStat)
	{
		UP_Tlv5APANStat = 0;
		UP_HookExchWriteRecErr();
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	}
	if((UP_CardDataBuffer[UP_CardTLVSet.TVL82AIP.Seat]&0x20) == 0)
	{
		UP_HookExchWriteRecErr();
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	}
	if(UP_CardTLVSet.TVL5APAN.Len == 0)
	{
		UP_HookExchWriteRecErr();
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	}
	return UP_CARD_SUCC;//交易成功
}

/*
**************************************************************************************************************
*                                         CPU卡，发送消费命令后，卡离开等异常处理  
*  参 数：  0      CPU卡消费
*           非0    CPU卡充值
*                    
*  返 回：  9000   成功
*         非9000   失败
**************************************************************************************************************
*/
U16 UP_CpuCard_ErrProc( U08 *TlvBuffer, U08 TlvBufferlen, U32 CardDataBufferNumTmp, U08 *ErrRec )
{
//	U32 recnum,maxrecnum;
	U16 rcode=0;	
	UP_HookExchWriteRecErr();							    
	KK:
//====================>> (1) 等待卡
	ICC_PCD_RadioOff();								//卡下电	
	if(ReRequestCardToActive() == 0xffff)
	{
		return 4;
	}	
	
	rcode = UP_CpuCard_SubErrProcInc(TlvBuffer, TlvBufferlen, CardDataBufferNumTmp, ErrRec);  					//CPU卡交易异常处理 消费   
	if(rcode == 1)
	{goto KK;}
	
	return rcode;										 
}

/*
**************************************************************************************************************
*                                         CPU卡消费异常处理
**************************************************************************************************************
*/
U16 UP_CpuCard_SubErrProcInc( U08 *TlvBuffer, U08 TlvBufferlen, U32 CardDataBufferNumTmp, U08 *ErrRec )
{
    U08 IcBackBalance[6];
    U16 rcode;
	U08 buf[20];
	_INT_32_08  TmpMoney;
	U08 *str;	
	U32 CardTmp;
	CardTmp = UP_CardDataBufferNum;										 
/*
***************************************************************************************************
*  〖0〗 选择主目录
***************************************************************************************************
*/
	rcode = ICF_SelectAID( "2PAY.SYS.DDF01", 0x0E, UP_Icc );  
	if( rcode != 0x9000 )						//选择PSE 
	{
		return 1; 
	}
//	if( gpRcvBuffer[1] != ( Grcv_Len - 2 ) )	//FCI格式错误	(File Control Information 文件控制信息) 
//	{
//		return 1;
//	}
	rcode = ICF_SelectAID( (const unsigned char *)UP_ICPParm.TVL9F06, UP_ICPParm.TVL9F06Len, UP_Icc );   
	if( rcode != 0x9000 )						//选择PSE 
	{
		return 1; 
	}
//	if( gpRcvBuffer[1] != ( Grcv_Len - 2 ) )	//FCI格式错误	(File Control Information 文件控制信息) 
//	{
//		return 1;
//	}
	rcode = ICF_ReadRecord( ErrRec[0], ErrRec[1], 0, UP_Icc );
	if( rcode != 0x9000 )				
	{
		return 1;
	}	    
	
	rcode = UP_TlvDataAnalysisAndFarming(&gpRcvBuffer[0], (U16)Grcv_Len-2, buf, buf, 1);
	if(rcode)
	{
		rcode = 1;
		goto END;
	}
	
	if(ErrRec[2])
	{
		if(gpRcvBuffer[1]&0x80)
		{
			if(ErrRec[0]>10)
			{
				memcpy(UP_sdata+UP_sdatalen,&gpRcvBuffer[0],Grcv_Len);
				UP_sdatalen += Grcv_Len;
			}
			else
			{
				memcpy(UP_sdata+UP_sdatalen,&gpRcvBuffer[3],gpRcvBuffer[2]);
				UP_sdatalen += gpRcvBuffer[2];
			}
			
		}
		else
		{
			if(ErrRec[0]>10)
			{
				memcpy(UP_sdata+UP_sdatalen,&gpRcvBuffer[0],Grcv_Len);
				UP_sdatalen += Grcv_Len;
			}
			else
			{
				memcpy(UP_sdata+UP_sdatalen,&gpRcvBuffer[2],gpRcvBuffer[1]);
				UP_sdatalen += gpRcvBuffer[1];
			}
		}		
	}
	if(UP_PosTLVSet.TVLDF60Data)
	{
		rcode = ICF_GetTransProve(&UP_CardDataBuffer[UP_CardTLVSet.TVL9F36APPCOUNT.Seat],&UP_CardDataBuffer[UP_CardDataBufferNum], UP_Icc);
		if(rcode == 0x9000)
		{
			if(UP_CardTLVSet.TVL9F26AC.Len==0)
			{
				UP_CardTLVSet.TVL9F26AC.Len = 8;
				UP_CardTLVSet.TVL9F26AC.Seat = UP_CardDataBufferNum;
			}
			return 0;
		}
		else if(UP_TradeInformation.DealMoney == 0)
		{
			if(rcode == 0x9406)
			{
				rcode = 2;
				goto END;
			}
			rcode = 1;
			goto END;
		}
	}
	rcode = UP_GPO( TlvBuffer, TlvBufferlen, UP_Icc );
	if(rcode != 0x9000)							 //一般读取ED余额需验证个人密码PIN 
	{	
		rcode = 1;
		goto END;
	}
	memset(buf, 0, 20);
	str = UP_FindSeatOfTLV( &gpRcvBuffer[2], gpRcvBuffer[1], "\x9F\x5D", 2 );
	if(str)									
	{
		memcpy(IcBackBalance,str+3,6);
		sprintf((char*)buf,"%02X%02X%02X%02X%02X%02X", IcBackBalance[0],IcBackBalance[1], IcBackBalance[2], IcBackBalance[3], IcBackBalance[4],IcBackBalance[5] );		   	//保存卡内余额
	
		TmpMoney.Int32Bit = atoi((const char*)buf);
		if( ( UP_TradeInformation.DealMoney != 0 ) && 
		    ( TmpMoney.Int32Bit+2*UP_TradeInformation.DealMoney == UP_TradeInformation.OldPurseBalance ) )
		{ 	
			UP_TradeInformation.NewPurseBalance = TmpMoney.Int32Bit+UP_TradeInformation.DealMoney;
			return 0; 
		} 
		else
		{
			rcode = 2;
			goto END;
		}
	}
	if(ErrRec[6])
	{
		rcode = UP_GetBalanceEC(IcBackBalance, UP_Icc);
		if( rcode != 0x9000 )							 //一般读取ED余额需验证个人密码PIN 
		{
			rcode = 1;
			goto END;
		}
		memset(buf, 0, 20);
		sprintf((char*)buf,"%02X%02X%02X%02X%02X%02X", IcBackBalance[0], IcBackBalance[1], IcBackBalance[2], IcBackBalance[3], IcBackBalance[4], IcBackBalance[5]);
		TmpMoney.Int32Bit = atoi((const char*)buf);
		if( ( UP_TradeInformation.DealMoney != 0 ) && 
		    ( TmpMoney.Int32Bit+2*UP_TradeInformation.DealMoney == UP_TradeInformation.OldPurseBalance ) )
		{ 	
			UP_TradeInformation.NewPurseBalance = TmpMoney.Int32Bit+UP_TradeInformation.DealMoney;
			return 0; 
		} 
		else 
		{
			rcode = 2;
			goto END;
		}
	}
	if(ErrRec[3])
	{
		rcode = ICF_ReadRecord( ErrRec[4], ErrRec[5], 0, UP_Icc );
		if( rcode != 0x9000 )				
		{
			rcode = 1;
			goto END;
		}
		memset(buf, 0, 20);
		str = UP_FindSeatOfTLV( &gpRcvBuffer[2], gpRcvBuffer[1], "\x9F\x5D", 2 );
		if(str)									
		{
			memcpy(IcBackBalance,str+3,6);
			sprintf((char*)buf,"%02X%02X%02X%02X%02X%02X", IcBackBalance[0],IcBackBalance[1], IcBackBalance[2], IcBackBalance[3], IcBackBalance[4],IcBackBalance[5] );		   	//保存卡内余额
			  
			TmpMoney.Int32Bit = atoi((const char*)buf);
			if( ( UP_TradeInformation.DealMoney != 0 ) && 
		    ( TmpMoney.Int32Bit+2*UP_TradeInformation.DealMoney == UP_TradeInformation.OldPurseBalance ) )
			{ 	
				UP_TradeInformation.NewPurseBalance = TmpMoney.Int32Bit+UP_TradeInformation.DealMoney;
				return 0; 
			} 
			else 
			{
				rcode = 2;
				goto END;
			}
		}
	}
	END:
	UP_CardDataBufferNum = CardTmp;
    return rcode;
}
/*
**************************************************************************************************************
*    检查存储器、公钥下载、IC卡参数下载状态
**************************************************************************************************************
*/
U32 UP_Card_CheckMemoryCaKeyAndIcPar( void )
{
	U32 sta;
	U32 rcode;
	if(UP_SysCfg.NormalOrShow == 0)
	{
		if( (UP_SysCfg.CAPKeyAndICParmSta & 0x01) == 1 )
		{
			return UP_CARD_NPUBKEY;
		}														
		if( (UP_SysCfg.CAPKeyAndICParmSta & 0x02) == 2 )
		{
			return UP_CARD_NICPAR;
		}
	}
	rcode = APP_Get_RecFileStat( UP_Rec_Config.UP_RecMemoryBank_Trade, &sta );
	if( rcode != 0 )
	{
		return UP_CARD_MEMERR;		
	}
	if( sta != 0 )
	{
		return UP_CARD_MEMFULL;
	}		
	rcode = APP_Get_RecFileStat( UP_Rec_Config.UP_RecMemoryBank_TradeRec, &sta );
	if( rcode != 0 )
	{
		return UP_CARD_MEMERR;		
	}
	if( sta != 0 )
	{
		return UP_CARD_MEMFULL;
	}
	return UP_CARD_SUCC;
}
/*
**************************************************************************************************************
*    GPO命令返回中必要数据检查
**************************************************************************************************************
*/
U32 UP_Card_CheckTLVData_Necessary( void )
{			
//	U08 IcBackBalance[6];
//	U16 rcode;									
	if(UP_CardTLVSet.TVL82AIP.Len == 0)
	{
//		DisplayClearAll( 0 ); 
////		DisplayString( 0, 0, 0, 1, 0, " GPO命令返回中  ", 0 );
////   		DisplayString( 0, 0, 0, 3, 0, "   缺少82标签   ", 0 );
////		DisplayString( 0, 0, 0, 5, 0, "    脱机拒绝    ", 0 );
//		DisplayString( 0, 0, 0, 5, 0, "    交易拒绝    ", 0 );
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	}
	if(UP_CardTLVSet.TVL82AIP.Len != 2)
	{
//		DisplayClearAll( 0 ); 
////		DisplayString( 0, 0, 0, 1, 0, " GPO命令返回中  ", 0 );
////   		DisplayString( 0, 0, 0, 3, 0, "   缺少82标签   ", 0 );
////		DisplayString( 0, 0, 0, 5, 0, "    脱机拒绝    ", 0 );
//		DisplayString( 0, 0, 0, 5, 0, "    交易拒绝    ", 0 );
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	}
	
	if(UP_CardTLVSet.TVL9F10BCZDY.Len == 0)
	{
//		DisplayClearAll( 0 ); 
//		DisplayString( 0, 0, 0, 1, 0, " GPO命令返回中  ", 0 );
//   	DisplayString( 0, 0, 0, 3, 0, "  缺少9F10标签  ", 0 );
//		DisplayString( 0, 0, 0, 5, 0, "    脱机拒绝    ", 0 );
//		DisplayString( 0, 0, 0, 5, 0, "    交易拒绝    ", 0 );
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	}
	if((UP_CardDataBuffer[UP_CardTLVSet.TVL9F10BCZDY.Seat+4]&0x30) != 0x10)
	{	
		if((UP_CardTLVSet.TVL9F36APPCOUNT.Len ==0 )||(UP_CardTLVSet.TVL82AIP.Len == 0)||(UP_CardTLVSet.TVL9F26AC.Len ==0 )||(UP_CardTLVSet.TVL57CD2.Len == 0))
		{
			DEF_SysCard_Debug;
			return UP_CARD_UNKNOWN;
		}
		if(UP_CardTLVSet.TVL5F34PANINDEX.Len == 0)
		{
			DEF_SysCard_Debug;
			return UP_CARD_UNKNOWN;	
		}
		if(UP_CardTLVSet.TVL9F6C.Len == 0)
		{
			DEF_SysCard_Debug;
			return UP_CARD_UNKNOWN;	
		}
		if(UP_CardTLVSet.TVL9F5D.Len == 0)
		{
			DEF_SysCard_Debug;
			return UP_CARD_UNKNOWN;	
		}
		if(UP_CardTLVSet.TVL5F20NAME.Len == 0)
		{
			DEF_SysCard_Debug;
			return UP_CARD_UNKNOWN;	
		}
	}
	else
	{
		if(UP_CardTLVSet.TVL94AFL.Len ==0 )
		{
			DEF_SysCard_Debug;
			return UP_CARD_UNKNOWN;
		}
	}
	
//	if(UP_CardTLVSet.TVL94AFL.Len ==0 )
//	{
//		DisplayClearAll( 0 ); 
//		DisplayString( 0, 0, 0, 1, 0, " GPO命令返回中  ", 0 );
//		DisplayString( 0, 0, 0, 3, 0, "   缺少94标签   ", 0 );    
//		DisplayString( 0, 0, 0, 5, 0, "    脱机拒绝    ", 0 );
//		DisplayString( 0, 0, 0, 5, 0, "    交易拒绝    ", 0 );
//		return 15;
//	}
	if(UP_CardTLVSet.TVL9F36APPCOUNT.Len ==0 )
	{
//		DisplayClearAll( 0 ); 
//		DisplayString( 0, 0, 0, 1, 0, " GPO命令返回中  ", 0 );
//		DisplayString( 0, 0, 0, 3, 0, "  缺少9F36标签  ", 0 );      
//		DisplayString( 0, 0, 0, 5, 0, "    脱机拒绝    ", 0 );
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	}
	if(UP_CardTLVSet.TVL9F26AC.Len ==0 )
	{
//		DisplayClearAll( 0 ); 
//		DisplayString( 0, 0, 0, 1, 0, " GPO命令返回中  ", 0 );
//		DisplayString( 0, 0, 0, 3, 0, "  缺少9F26标签  ", 0 );     
//		DisplayString( 0, 0, 0, 5, 0, "    脱机拒绝    ", 0 );
//		DisplayString( 0, 0, 0, 5, 0, "    交易拒绝    ", 0 );
		DEF_SysCard_Debug;
		return UP_CARD_UNKNOWN;
	}
	if((UP_CardDataBuffer[UP_CardTLVSet.TVL9F10BCZDY.Seat+4]&0x30) != 0x10)
	{
//		DisplayClearAll( 0 ); 
//		DisplayString( 0, 0, 0, 3, 0, " 9F10标签状态为 ", 0 );   
//		DisplayString( 0, 0, 0, 5, 0, "    脱机拒绝    ", 0 );
//		DisplayString( 0, 0, 0, 5, 0, "    交易拒绝    ", 0 );
		DEF_SysCard_Debug;
		return UP_CARD_REJECT;
	}
	return UP_CARD_SUCC;
}
/*
**************************************************************************************************************
*    交易金额检查
**************************************************************************************************************
*/
U32 UP_Card_CheckTradeMoney( void )
{
//	U08 IcBackBalance[6];
//	U16 rcode;
//	U08 buf[20]={0};
//	rcode = UP_GetBalanceEC(IcBackBalance, UP_Icc);	 //读取电子现金余额
//	if( rcode != 0x9000 )							
//	{
//		DisplayClearAll( 0 );
//		DisplayString( 0, 0, 0, 1, 0, " 读取QPBOC电子  ", 0 );
//		DisplayString( 0, 0, 0, 3, 0, "  现金余额失败  ", 0 );
//		sprintf((char*)buf,"错误码：%04X",rcode);
//		DisplayString( 0, 0, 0, 5, 0, buf, 0 );     
//		return 15;
//	}
//	memset(buf, 0, 20);
//	sprintf((char*)buf,"%02X%02X%02X%02X%02X%02X", IcBackBalance[0], IcBackBalance[1], IcBackBalance[2], IcBackBalance[3], IcBackBalance[4], IcBackBalance[5]);
//	UP_TradeInformation.OldPurseBalance = atoi((const char*)buf);	//保存卡内余额	
//	if( UP_TradeInformation.DealMoney > UP_TradeInformation.OldPurseBalance )
//	{                                               //消费金额 低于钱包余额 禁止消费 
//		DisplayClearAll( 0 );
//		DisplayString( 0, 0, 0, 3, 0, "    余额不足    ", 0 );	
//		return 80;        
//	}
//	if(UP_TradeInformation.DealMoney == 0)
//	{
//		return UP_CARD_ZERO;
//	}
//	if(UP_TradeInformation.DealMoney>=UP_PosTLVSet.PosConsumptionlimits)
//	{
//		DisplayClearAll( 0 ); 
//		DisplayString( 0, 0, 0, 2, 0, "超出终端最低限额", 0 );
//		DisplayString( 0, 0, 0, 4, 0, "    交易终止    ", 0 );
//		return 15;
//	}
//	if(UP_TradeInformation.DealMoney>UP_PosTLVSet.ECConsumptionlimits)
//	{
//		DisplayClearAll( 0 ); 
//		DisplayString( 0, 0, 0, 3, 0, "  超出电子现金  ", 0 );
//		DisplayString( 0, 0, 0, 5, 0, "  脱机交易限额  ", 0 );
//		return 15;
//	}
	if(UP_TradeInformation.DealMoney>=UP_SysCfg.QpbocConsumptionlimits)
	{	
		return UP_CARD_LIMITMONEY;
	}
//	if(UP_TradeInformation.DealMoney<UP_PosTLVSet.QpbocLowestConsumptionlimits)
//	{
//		DisplayClearAll( 0 ); 
//		DisplayString( 0, 0, 0, 3, 0, "   低于非接触   ", 0 );	
//		DisplayString( 0, 0, 0, 5, 0, "  最低消费限额  ", 0 );
//		return 15;
//	}

//	buf[0] = UP_TradeInformation.DealMoney.Int08Bit.HH;
//	buf[1] = UP_TradeInformation.DealMoney.Int08Bit.HL;
//	buf[2] = UP_TradeInformation.DealMoney.Int08Bit.LH;
//	buf[3] = UP_TradeInformation.DealMoney.Int08Bit.LL;
//	if( memcmp(buf, UP_ICPParm.TVL9F1B, UP_ICPParm.TVL9F1BLen)<0 )
//	{      
//	    DisplayClearAll( 0 );                                   
//		DisplayString( 0, 0, 0, 3, 0, "低于最低消费限额", 0 );	 
//		   
//		 	   
//		return 20;        
//	}
//	if( memcmp(UP_ICPParm.TVL9F7B, &UP_CardDataBuffer[UP_TradeTLVSet.TVL9F02.Seat+6-UP_ICPParm.TVL9F7BLen], UP_ICPParm.TVL9F7BLen)<0 )
//	{      
//	    DisplayClearAll( 0 );                                   
//		DisplayString( 0, 0, 0, 1, 0, "   超出电子现   ", 0 );
//		DisplayString( 0, 0, 0, 3, 0, "   金交易限额   ", 0 );	 
//		   
//		 	  
//		return 20;        
//	}	 
//	if( memcmp(IcBackBalance, &UP_CardDataBuffer[UP_TradeTLVSet.TVL9F02.Seat], 6)<0 )
//	{                                               //消费金额 大于钱包余额 禁止消费 
//		  
//		 	   //by zkw 语音
//		ICC_PCD_RadioOff(); ();
//		return 20;        
//	}
	return UP_CARD_SUCC;
}
/*
**************************************************************************************************************
CPU卡检测  
**************************************************************************************************************
*/
U32 UP_CPUCard_Check(void)
{	 
	U32 rcode;
	rcode = UP_Card_SelectPPSE( );
	if( rcode )			           
	{ goto END; }	
	
	rcode = UP_Card_Check( );  //【1】 卡片校验    这里有可能是用户卡或其它卡
	END:
	return rcode;
}
/*
**************************************************************************************************************
银联卡从记录文件中获取卡号	 在“UP_CPUCard_Check”之后调用
输入参数：	PANFileSFI		记录文件SFI
			PANFileRecNum	记录号
输出参数:	Pan5A			标签5A中卡号部分　此缓冲区不小于10字节	 卡帐号以"F"结尾 
  			Pan5Alen		标签5A中卡号部分长度
返回：0:获取卡号成功		非0:获取卡号失败 
**************************************************************************************************************
*/
U32 UP_CPUCard_GetPANByRec(U08 PANFileSFI, U08 PANFileRecNum, U08 *Pan5A, U32 *Pan5Alen)
{
	U32 rcode;
	U08 *str;
	rcode = ICF_ReadRecord( PANFileSFI, PANFileRecNum, 0, UP_Icc );
	if( rcode != 0x9000 )				
	{
		return rcode;		
	} 
	str = UP_FindSeatOfTLV( &gpRcvBuffer[2], gpRcvBuffer[1], "\x5A", 1 );
	if(str)
	{
		memcpy(Pan5A,str+2,str[1]); 
		*Pan5Alen = str[1];
		return 0;
	}
	return 1;	
}
/*
**************************************************************************************************************
银联卡从记录文件中获取标签
输入参数：	PANFileSFI		记录文件SFI
			PANFileRecNum	记录号
输出参数:	Type			标签类型
  			TLen			标签类型长度
输出参数:	Value			标签值
  			VLen		标签值长度
返回：0:获取标签成功		非0:获取标签失败 
**************************************************************************************************************
*/
U32 UP_CPUCard_GetTLVByRec(U08 PANFileSFI, U08 PANFileRecNum, U08 *Type, U32 TLen, U08 *Value, U32 *VLen)
{
	U32 rcode;
	U08 *str;
	rcode = ICF_ReadRecord( PANFileSFI, PANFileRecNum, 0, UP_Icc );
	if( rcode != 0x9000 )				
	{
		return rcode;		
	} 
	str = UP_FindSeatOfTLV( &gpRcvBuffer[2], gpRcvBuffer[1], Type, TLen );
	if(str)
	{
		memcpy(Value,str+2,str[1]); 
		*VLen = str[1];
		return 0;
	}
	return 1;	
}
/*
**************************************************************************************************************
银联卡消费初始化 
输入参数：	DealMoney		交易金额
输出参数:	Bin57			标签57中卡号部分　此缓冲区不小于10字节	 卡帐号以"D"结尾 
  			Bin57len		标签57中卡号部分长度　　如果没有标签57则返回0
返回：0:成功		非0:失败 
**************************************************************************************************************
*/					  
U32 UP_CPUCard_ExchInit(U32 DealMoney, U08 *Bin57, U32 *Bin57len)
{
	U32 rcode;
	U32 i;
	UP_TradeInformation.DealMoney = DealMoney;
	
	rcode = UP_Card_ExchInit( );	//【3】 写卡，完成交易     
	if(rcode == 0)
	{
		*Bin57len = 0;
		for(i=0;i<UP_CardTLVSet.TVL57CD2.Len;i++)
		{
			if(((UP_CardDataBuffer[UP_CardTLVSet.TVL57CD2.Seat+i]&0xF0) !=0xD0 )&&((UP_CardDataBuffer[UP_CardTLVSet.TVL57CD2.Seat+i]&0x0F) !=0x0D ))
			{
				(*Bin57len)++;	
			}
			else if(((UP_CardDataBuffer[UP_CardTLVSet.TVL57CD2.Seat+i]&0x0F) ==0x0D ))
			{
				(*Bin57len)++;	
			 	break;
			}
			else if(((UP_CardDataBuffer[UP_CardTLVSet.TVL57CD2.Seat+i]&0xF0) ==0xD0 ))
			{
			 	break;
			}
		}
		if(*Bin57len>10)
		{*Bin57len = 10;}
		if(*Bin57len)
		{
			memcpy(Bin57, &UP_CardDataBuffer[UP_CardTLVSet.TVL57CD2.Seat], *Bin57len);
		}
	}
	ExchInitStat = rcode;
	return rcode;
}
/*
**************************************************************************************************************
*                               在“UP_CPUCard_ExchInit”之后获取余额  
*  参  数：无
*  返  回：余额
**************************************************************************************************************
*/
U32 UP_Card_GetBalancebehindInit(void)
{
	U08 buf[20],IcBackBalance[6];
	if((UP_CardTLVSet.TVL9F5D.Len==0)&&(UP_CardTLVSet.TVL9F79ECBALANCE.Len==0))	
	{
		if( UP_GetBalanceEC(IcBackBalance, UP_Icc) == 0x9000 )		//读取电子现金余额					
		{
			UP_CardTLVSet.TVL9F79ECBALANCE.Len = 6;		//电子现金余额			   6	R	n
			UP_CardTLVSet.TVL9F79ECBALANCE.Seat = UP_CardDataBufferNum;
			memcpy(&UP_CardDataBuffer[UP_CardDataBufferNum], IcBackBalance, 6);
			UP_CardDataBufferNum += 6;
			sprintf((char*)buf,"%02X%02X%02X%02X%02X%02X", IcBackBalance[0], IcBackBalance[1], IcBackBalance[2], IcBackBalance[3], IcBackBalance[4], IcBackBalance[5]);
			UP_TradeInformation.NewPurseBalance = atoi((const char*)buf);	//保存卡内余额
			BalanceDisStat=1;
			ErrRec[6] = 1;
			if(ExchInitStat == UP_CARD_SUCC)
			{UP_TradeInformation.OldPurseBalance = UP_TradeInformation.NewPurseBalance+UP_TradeInformation.DealMoney;}
			else
			{
				UP_TradeInformation.OldPurseBalance = UP_TradeInformation.NewPurseBalance;
			}
		}
	}
	return UP_TradeInformation.OldPurseBalance;
}
/*
**************************************************************************************************************
银联卡消费扣钱
输入参数：	
输出参数:	Balance			余额
			Pan5A			标签5A中卡号部分　此缓冲区不小于10字节	 卡帐号以"F"结尾 
  			Pan5Alen		标签5A中卡号部分长度
返回：0:成功		非0:失败 
**************************************************************************************************************
*/
U32 UP_CPUCard_ToExch(U32 *Balance, U08 *Pan5A, U32 *Pan5Alen)
{
	U32 rcode;
	rcode = UP_Card_ToExch( );
	if( rcode )           		   //【3】 写卡，完成交易     
	{ goto END; }
	END:
	if(rcode == 0)
	{
		if(BalanceDisStat == 0)
		{UP_TradeInformation.NewPurseBalance = 0;}
		*Balance = UP_TradeInformation.NewPurseBalance;
		if(UP_CardTLVSet.TVL5APAN.Len>10)
		{UP_CardTLVSet.TVL5APAN.Len = 10;}
		*Pan5Alen = UP_CardTLVSet.TVL5APAN.Len;
		if(UP_CardTLVSet.TVL5APAN.Len)
		{
			memcpy(Pan5A, &UP_CardDataBuffer[UP_CardTLVSet.TVL5APAN.Seat], UP_CardTLVSet.TVL5APAN.Len);
		}
	}
	return rcode;
}
/*
**************************************************************************************************************
银联卡脱机认证
输入参数：	
返回：0:成功		非0:失败 
**************************************************************************************************************
*/
U32 UP_Card_fDDA(void)
{
	U32 rcode;
	if(UP_SysCfg.NormalOrShow == 0)
	{
		rcode = UP_Card_CardDDA();	//脱机数据认证
		if(rcode)
		{ 
			UP_HookExchWriteRecErr();
			return UP_CARD_DDAERR;
		}
	}
	UP_HookExchWriteRec( UP_Rec_Config.UP_RecMemoryBank_Trade, UP_RecType_UPCashTrade );		//保存记录
	return UP_CARD_SUCC;//交易成功
}

